-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make the necessary changes to support concurrency in Miri. #70598
Conversation
Oh wow, thanks a lot! I expected this to take way longer. ;) I'd like to review this, too, before it lands. But it may take a week or two until I find the time.
|
I tried to make a minimal first step. There is still a lot of work to do, but my hope is that all of it will be on the Miri side.
Currently, each PR I create needs to get an approval from our legal department, which may take up to a week. If you think that it is still worth doing this, please let me know.
Data races are currently not supported. I think that adding a vector-clock based data race detection to all memory accesses is likely to significantly degrade the performance. I will add a comment to README and a warning as you suggest. By the way, do stacked borrows rule out data-races except on UnsafeCell?
I started learning about TLS only when I started working on this PR, so it is very likely that I do not understand something.
Could you please point me to the code that is supposed to do this thread-local allocation? The reason why I changed Is my reasoning clear and do you see what I missed? |
With raw pointers it is possible to create data-races even with stacked borrows. |
oO The thing is, I want to avoid a situation where Miri does not work with rustc master. The Miri-side PR will likely take a while to review as it is much bigger, and new shims just tend to be a lot of effort (plus there is usually some first-time-contributor effect). If we cannot land this one here without breaking Miri or blocking on that big review, we have to wait until both PRs are completely reviewed before landing anything. This might mean more rebasing for you on the rustc side. I have a preference for being able to land independent changes, but if you are fine with doing the rebases and not landing the rustc PR until both PRs are fully reviewed, I could live with that. I hope you don't need to wait another week for each adjustment we request in this PR?
If you also exclude raw pointers (as pointed out by @bjorn3), I think so, but have not formally proven it.
You clearly know more about TLS than I do; I didn't even know "thread-local statics" were a thing. When I referred to thread-local storage I was thinking of the APIs we are already shimming in Miri via |
Yes #![feature(thread_local)]
#[thread_local]
static A: u8 = 0;
pub fn get_a_ref() -> *const u8 {
&A
} target triple = "x86_64-unknown-linux-gnu"
@_ZN10playground1A17hfc698d88543494bfE = internal thread_local constant <{ [1 x i8] }> zeroinitializer, align 1, !dbg !0
; playground::get_a_ref
; Function Attrs: nonlazybind uwtable
define i8* @_ZN10playground9get_a_ref17h42f05c46255e0587E() unnamed_addr #0 !dbg !11 {
start:
ret i8* getelementptr inbounds (<{ [1 x i8] }>, <{ [1 x i8] }>* @_ZN10playground1A17hfc698d88543494bfE, i32 0, i32 0, i32 0), !dbg !15
} In cg_clif the logic for tls can be found at https://github.com/bjorn3/rustc_codegen_cranelift/blob/c2e35604474aa25479dcca231fbc393a941234da/src/constant.rs#L64 to ensure that the const pointing to the static is directly codegened as taking the reference of the static rather than loading the from an allocation that contains the pointer. And at https://github.com/bjorn3/rustc_codegen_cranelift/blob/c2e35604474aa25479dcca231fbc393a941234da/src/constant.rs#L251 the static allocation is marked as thread local.
One of the things I used while implementing TLS for Cranelift was https://akkadia.org/drepper/tls.pdf. It describes the ABI level of TLS for ELF executables. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I am fine with doing rebases. |
89adcb6
to
ce0a8ab
Compare
This comment has been minimized.
This comment has been minimized.
ce0a8ab
to
3d2d8ea
Compare
☔ The latest upstream changes (presumably #70672) made this pull request unmergeable. Please resolve the merge conflicts. |
If we implement #70685 before this PR the interactions will become much clearer, but we can also punt that to the future and merge this PR. I'm fine either way |
☔ The latest upstream changes (presumably #70726) made this pull request unmergeable. Please resolve the merge conflicts. |
Sorry, I assumed since the last comments were on documentation and these were addressed, that this was ready to go. |
…_const and add an additional comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, thank you so much for working on this and doing some drive-by fixes (frame_idx
).
r=me with the last nit fixed.
…nforce_ method group.
b132a21
to
cbd9222
Compare
@bors r=oli-obk,RalfJung |
📌 Commit cbd9222 has been approved by |
⌛ Testing commit cbd9222 with merge 61ec4ad1640bdbdcfc01ab4be1a9f20445d6c823... |
@bors retry yield |
☀️ Test successful - checks-azure |
Move the stack to the evaluator. (no-op PR for 70598) The changes to Miri to make it to compile with Rustc PR rust-lang/rust#70598.
Move the stack to the evaluator. (no-op PR for 70598) The changes to Miri to make it to compile with Rustc PR rust-lang/rust#70598.
Move the stack to the evaluator. (no-op PR for 70598) The changes to Miri to make it to compile with Rustc PR rust-lang/rust#70598.
Oh, this looks really exciting from the title of the PR. Does this mean that |
Yes it will just work (once rust-lang/miri#1284 lands). :) UB checks for synchronization primitives are incomplete, and there is no data race detection, but the code runs at least. Just check the testcases in rust-lang/miri#1284. :D |
Implement basic support for concurrency (Linux/macos only) Changes (most new code is in `src/threads.rs` and `src/shims/foreign_items/posix.rs`): 1. Move the stack from `Machine` to a newly created `Thread` struct. 2. Add a `ThreadSet` struct that manages the threads. 3. Change `canonical_alloc_id` to create a unique allocation id for each thread local and thread (the responsible struct is `ThreadLocalStorage`) 4. Change the code to execute the thread local destructors immediately when a thread terminates. 5. Add the most basic round-robin scheduler. This pull request depends on [these changes to the compiler](rust-lang/rust#70598).
This pull request makes the necessary changes to the Rust compiler to allow Miri to support concurrency:
InterpCx
) to machine, so that the machine can switch the stacks when it changes the thread being executed.r? @oli-obk
cc @RalfJung